import sqlite3 from 'sqlite3';
import { MemoryRecord, MemoryType, ErrorPattern } from './types.js';
import { MemoryAnalyzer } from './analyzer.js';
import path from 'path';
import fs from 'fs';
import os from 'os';

// 定义数据库行的接口
interface MemoryRow {
    id: number;
    type: string;
    content: string;
    context: string | null;
    tags: string | null;
    timestamp: number;
}

interface ErrorPatternRow {
    id: number;
    pattern: string;
    frequency: number;
    solutions: string | null;
    last_updated: number;
}

/**
 * 记忆存储类
 * 负责记忆的持久化存储和检索
 */
export class MemoryStorage {
    private db: sqlite3.Database;
    private dbPath: string;
    private initialized: boolean = false;

    /**
     * 构造函数
     * @param dbPath 数据库路径，默认为用户主目录下的 .ai-memory.db
     */
    constructor(dbPath?: string) {
        this.dbPath = dbPath || path.join(os.homedir(), '.ai-memory.db');

        // 确保目录存在
        const dir = path.dirname(this.dbPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }

        // 打开数据库连接
        this.db = new sqlite3.Database(this.dbPath);
    }

    /**
     * 初始化数据库
     * 创建必要的表和索引
     */
    async initialize(): Promise<void> {
        if (this.initialized) return;

        return new Promise<void>((resolve, reject) => {
            const self = this; // 保存 this 引用

            // 创建记忆表
            this.db.run(`
                CREATE TABLE IF NOT EXISTS memories (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    type TEXT NOT NULL,
                    content TEXT NOT NULL,
                    context TEXT,
                    tags TEXT,
                    timestamp INTEGER NOT NULL
                )
            `, (err) => {
                if (err) {
                    reject(err);
                    return;
                }

                // 创建错误模式表
                self.db.run(`
                    CREATE TABLE IF NOT EXISTS error_patterns (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        pattern TEXT NOT NULL UNIQUE,
                        frequency INTEGER NOT NULL DEFAULT 1,
                        solutions TEXT,
                        last_updated INTEGER NOT NULL
                    )
                `, (err) => {
                    if (err) {
                        reject(err);
                        return;
                    }

                    // 创建索引
                    self.db.run(`
                        CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
                        CREATE INDEX IF NOT EXISTS idx_memories_timestamp ON memories(timestamp);
                        CREATE INDEX IF NOT EXISTS idx_memories_tags ON memories(tags);
                    `, (err) => {
                        if (err) {
                            reject(err);
                            return;
                        }

                        self.initialized = true;
                        resolve();
                    });
                });
            });
        });
    }

    /**
     * 存储记忆
     * @param type 记忆类型
     * @param content 记忆内容
     * @param context 上下文
     * @param tags 标签
     * @returns 存储的记忆ID
     */
    async storeMemory(
        type: MemoryType,
        content: string,
        context?: string,
        tags?: string
    ): Promise<number> {
        await this.initialize();

        return new Promise<number>((resolve, reject) => {
            const timestamp = Date.now();

            const self = this; // 保存 this 引用
            this.db.run(
                `INSERT INTO memories (type, content, context, tags, timestamp) VALUES (?, ?, ?, ?, ?)`,
                [type, content, context || null, tags || null, timestamp],
                function (err) {
                    if (err) {
                        reject(err);
                        return;
                    }

                    // 如果是错误类型，处理错误模式
                    if (type === MemoryType.ERROR) {
                        const pattern = MemoryAnalyzer.extractErrorPattern(content);
                        self.updateErrorPattern(pattern); // 使用保存的 this 引用
                    }

                    resolve(this.lastID);
                }
            );
        });
    }

    /**
     * 更新错误模式
     * @param pattern 错误模式
     */
    private updateErrorPattern(pattern: string): void {
        const timestamp = Date.now();
        const self = this; // 保存 this 引用

        // 尝试更新现有模式
        this.db.run(
            `UPDATE error_patterns SET frequency = frequency + 1, last_updated = ? WHERE pattern = ?`,
            [timestamp, pattern],
            function (err) {
                if (err) {
                    console.error('更新错误模式失败:', err);
                    return;
                }

                // 如果没有更新任何行，插入新模式
                if (this.changes === 0) {
                    self.db.run(
                        `INSERT INTO error_patterns (pattern, frequency, last_updated) VALUES (?, 1, ?)`,
                        [pattern, timestamp],
                        function (err) {
                            if (err) {
                                console.error('插入错误模式失败:', err);
                            }
                        }
                    );
                }
            }
        );
    }

    /**
     * 检索记忆
     * @param type 记忆类型
     * @param limit 限制数量
     * @param offset 偏移量
     * @param tags 标签过滤
     * @param searchText 搜索文本
     * @returns 记忆记录列表
     */
    async retrieveMemories(
        type?: MemoryType,
        limit: number = 10,
        offset: number = 0,
        tags?: string,
        searchText?: string
    ): Promise<MemoryRecord[]> {
        await this.initialize();

        let query = `SELECT * FROM memories`;
        const params: any[] = [];

        // 构建WHERE子句
        const conditions: string[] = [];

        if (type) {
            conditions.push(`type = ?`);
            params.push(type);
        }

        if (tags) {
            conditions.push(`tags LIKE ?`);
            params.push(`%${tags}%`);
        }

        if (searchText) {
            conditions.push(`(content LIKE ? OR context LIKE ?)`);
            params.push(`%${searchText}%`, `%${searchText}%`);
        }

        if (conditions.length > 0) {
            query += ` WHERE ${conditions.join(' AND ')}`;
        }

        // 添加排序和分页
        query += ` ORDER BY timestamp DESC LIMIT ? OFFSET ?`;
        params.push(limit, offset);

        return new Promise<MemoryRecord[]>((resolve, reject) => {
            this.db.all<MemoryRow>(query, params, (err, rows) => {
                if (err) {
                    reject(err);
                    return;
                }

                const memories: MemoryRecord[] = rows.map(row => ({
                    id: row.id,
                    type: row.type as MemoryType,
                    content: row.content,
                    context: row.context || undefined,
                    tags: row.tags || undefined,
                    timestamp: row.timestamp
                }));

                resolve(memories);
            });
        });
    }

    /**
     * 获取错误模式
     * @param limit 限制数量
     * @returns 错误模式列表
     */
    async getErrorPatterns(limit: number = 10): Promise<ErrorPattern[]> {
        await this.initialize();

        return new Promise<ErrorPattern[]>((resolve, reject) => {
            this.db.all<ErrorPatternRow>(
                `SELECT * FROM error_patterns ORDER BY frequency DESC LIMIT ?`,
                [limit],
                (err, rows) => {
                    if (err) {
                        reject(err);
                        return;
                    }

                    const patterns: ErrorPattern[] = rows.map(row => ({
                        id: row.id,
                        pattern: row.pattern,
                        frequency: row.frequency,
                        solutions: row.solutions || undefined,
                        lastUpdated: row.last_updated
                    }));

                    resolve(patterns);
                }
            );
        });
    }

    /**
     * 更新错误模式的解决方案
     * @param patternId 模式ID
     * @param solutions 解决方案
     * @returns 是否成功
     */
    async updateErrorSolution(patternId: number, solutions: string): Promise<boolean> {
        await this.initialize();

        return new Promise<boolean>((resolve, reject) => {
            this.db.run(
                `UPDATE error_patterns SET solutions = ? WHERE id = ?`,
                [solutions, patternId],
                function (err) {
                    if (err) {
                        reject(err);
                        return;
                    }

                    // 在回调函数中，this 指向 Statement 对象
                    resolve(this.changes > 0);
                }
            );
        });
    }

    /**
     * 删除记忆
     * @param id 记忆ID
     * @returns 是否成功
     */
    async deleteMemory(id: number): Promise<boolean> {
        await this.initialize();

        return new Promise<boolean>((resolve, reject) => {
            this.db.run(
                `DELETE FROM memories WHERE id = ?`,
                [id],
                function (err) {
                    if (err) {
                        reject(err);
                        return;
                    }

                    // 在回调函数中，this 指向 Statement 对象，所以可以直接使用 this.changes
                    const wasDeleted = this.changes > 0;
                    resolve(wasDeleted);
                }
            );
        });
    }

    /**
     * 清空特定类型的记忆
     * @param type 记忆类型
     * @returns 删除的记录数
     */
    async clearMemories(type?: MemoryType): Promise<number> {
        await this.initialize();

        return new Promise<number>((resolve, reject) => {
            let query = `DELETE FROM memories`;
            const params: any[] = [];

            if (type) {
                query += ` WHERE type = ?`;
                params.push(type);
            }

            this.db.run(query, params, function (err) {
                if (err) {
                    reject(err);
                    return;
                }

                // 在回调函数中，this 指向 Statement 对象，所以可以直接使用 this.changes
                const deletedCount = this.changes;
                resolve(deletedCount);
            });
        });
    }

    /**
     * 关闭数据库连接
     */
    close(): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            this.db.close(err => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve();
            });
        });
    }
}